#include "dtype.h"
#include "din.h"
#include "weight.h"
#include "bias.h"

#include <stdio.h>

#define CONV_OUT_CHANNEL    16
#define CONV_IN_CHANNEL     6
#define DIN_SIZE            14
#define DOUT_SIZE           10
#define KER_SIZE            5

dtype dout_c[16][10][10]={0.0f};

#define RELU(A) ((A) > 0 ? (A) : 0)

void conv2d_ic6s14_ko16i6s5_oc16s10(
    dtype din[CONV_IN_CHANNEL][DIN_SIZE][DIN_SIZE],
    dtype ker[CONV_OUT_CHANNEL][CONV_IN_CHANNEL][KER_SIZE][KER_SIZE],
    dtype bias[CONV_OUT_CHANNEL],
    dtype dout[CONV_OUT_CHANNEL][DOUT_SIZE][DOUT_SIZE]
){

    for (int index_out_ch = 0; index_out_ch < CONV_OUT_CHANNEL; index_out_ch++){
        for (int i = 0; i < DOUT_SIZE; i++){
            for (int j = 0; j < DOUT_SIZE; j++){
                dtype tmp = 0;
                for (int index_in_ch = 0; index_in_ch < CONV_IN_CHANNEL; index_in_ch++){
                    for (int k_i = 0; k_i < KER_SIZE; k_i++){
                        for (int k_j = 0; k_j < KER_SIZE; k_j++){
                            tmp +=  din[index_in_ch][i+k_i][j+k_j] *
                                    // ker[index_out_ch][index_in_ch][KER_SIZE-1-k_i][KER_SIZE-1-k_j]);
                                    ker[index_out_ch][index_in_ch][k_i][k_j];
                        }
                    }
                }
                dout[index_out_ch][i][j] = tmp + bias[index_out_ch];
                // dout[index_out_ch][i][j] = RELU(tmp + bias[index_out_ch]);
            }
        }
    }   
}

int main(int argc, char const *argv[])
{
    conv2d_ic6s14_ko16i6s5_oc16s10(
        (dtype (*)[14][14])din[0],
        (dtype (*)[6][5][5])weight, 
        (dtype *)bias, 
        dout_c);
    printf("%f\n", dout_c[0][0][0]);
    printf("%f\n", dout_c[0][0][1]);
    printf("%f\n", dout_c[0][0][2]);
    printf("%f\n", dout_c[0][0][3]);
    return 0;
}
